package com.lovol.gis.demo.controller;


import com.lovol.gis.demo.common.GeometryUtil;
import com.lovol.gis.demo.common.RasterUtil;
import com.lovol.gis.demo.common.ResultResponse;
import com.lovol.gis.demo.entity.DemoLine;
import com.lovol.gis.demo.entity.DemoPoint;
import com.lovol.gis.demo.entity.DemoPolygon;
import com.lovol.gis.demo.entity.MultiRaster;
import com.lovol.gis.demo.entity.dto.LineDTO;
import com.lovol.gis.demo.entity.dto.PointDTO;
import com.lovol.gis.demo.entity.dto.PolygonDTO;
import com.lovol.gis.demo.mapper.DemoLineMapper;
import com.lovol.gis.demo.mapper.DemoPointMapper;
import com.lovol.gis.demo.mapper.DemoPolygonMapper;
import com.lovol.gis.demo.mapper.MultiRasterMapper;
import com.lovol.gis.image.SingleBandService;
import geotrellis.raster.Tile;
import geotrellis.vector.Extent;
import org.apache.commons.lang3.StringUtils;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Envelope;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/gis/demo/")
public class TestController {

    @Resource
    DemoPointMapper pointMapper;
    @Resource
    DemoLineMapper lineMapper;
    @Resource
    DemoPolygonMapper polygonMapper;

    @Resource
    MultiRasterMapper multiRasterMapper;

    @PostMapping("/insertPoint")
    public ResultResponse insertPoint(@RequestBody PointDTO bean) {
        String wkt = GeometryUtil.pointWktString(bean.getX(), bean.getY());
        DemoPoint demoPoint = new DemoPoint();
        demoPoint.setGeom(wkt);
        demoPoint.setName(bean.getName());
        demoPoint.setValue(bean.getValue());
        int n = pointMapper.addEntity(demoPoint);
        return ResultResponse.ok(n);
    }

    @PostMapping("/insertLine")
    public ResultResponse insertLine(@RequestBody LineDTO bean) {
        Coordinate []coordinates = GeometryUtil.parseCoord(bean.getPoints());
        String lineWkt = GeometryUtil.lineWktString(coordinates);

        DemoLine line = new DemoLine();
        line.setGeom(lineWkt);
        line.setName(bean.getName());
        line.setValue(bean.getValue());

        int n = lineMapper.addEntity(line);
        return ResultResponse.ok(n);
    }

    @PostMapping("/insertPolygon")
    public ResultResponse insertPolygon(@RequestBody PolygonDTO bean) {
        Coordinate []coordinates = GeometryUtil.parseCoord(bean.getPoints());
        String polygonWkt = GeometryUtil.lineWktString(coordinates);

        DemoPolygon polygon = new DemoPolygon();
        polygon.setGeom(polygonWkt);
        polygon.setName(bean.getName());
        polygon.setValue(bean.getValue());

        int n = polygonMapper.addEntity(polygon);
        return ResultResponse.ok(n);


    }

    @GetMapping("/insertRaster")
    public ResultResponse insertRaster() {

//        File dir = new File("D:\\Data\\dem\\dem30\\shandongtif\\");
        File root = new File("D:\\Data\\dem\\dem30\\");
        File[] files = root.listFiles();
        int nCount =0;

        List<Coordinate> coordinates = new ArrayList<>();
        for (File dir: files) {
            for (File f: dir.listFiles()) {
                String fullName = f.getAbsolutePath();
                Envelope env = RasterUtil.getRasterBoundsIn4326(fullName);
                if (env != null) {
                    coordinates.clear();
                    coordinates.add(new Coordinate(env.getMinX(), env.getMinY()));
                    coordinates.add(new Coordinate(env.getMinX(), env.getMaxY()));
                    coordinates.add(new Coordinate(env.getMaxX(), env.getMaxY()));
                    coordinates.add(new Coordinate(env.getMaxX(), env.getMinY()));
                    coordinates.add(new Coordinate(env.getMinX(), env.getMinY()));
                    String polygonWkt = GeometryUtil.polygonWktString(coordinates);
                    MultiRaster multiRaster = new MultiRaster();
                    multiRaster.setGeom(polygonWkt);
                    multiRaster.setFilePath(fullName);
                    multiRasterMapper.addEntity(multiRaster);
                    nCount++;
                }
            }
        }
        return ResultResponse.ok(nCount);
    }

    @GetMapping("/multiraster/{z}/{x}/{y}")
    public void cornProgressDate(@PathVariable("z") Integer z,
                                 @PathVariable("x") Integer x,
                                 @PathVariable("y") Integer y,
                                 HttpServletResponse response) {
        response.setContentType("image/png");
        try {
            byte[] tile = null;
            Extent tileExtent = SingleBandService.getTileExtent(z,x,y,true);
            String extentWkt = GeometryUtil.extentWkt(tileExtent.xmin(),tileExtent.ymin(),tileExtent.xmax(),tileExtent.ymax());
            List<MultiRaster> list = multiRasterMapper.queryByPolygon(extentWkt);
            if(list!=null && list.size()>0){
                String [] files = new String[list.size()];
                for (int i = 0; i < list.size(); i++) {
                    files[i] = list.get(i).getFilePath();
                }
                Tile t = SingleBandService.getTile1(x,y,z,files);
                if(t!=null){

                }
            }


        } catch (Exception e) {

        }
    }


    /**
     * 二进制内容写入 HttpServletResponse
     *
     * @param content  内容
     * @param response
     */
    private void byteFill(byte[] content, HttpServletResponse response) {
        OutputStream os = null;
        InputStream is = null;
        try {
            is = new ByteArrayInputStream(content);
            os = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = is.read(bytes)) != -1) {
                os.write(bytes, 0, len);
            }
            os.flush();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                is.close();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
